package com.hxzy.config.security.handler;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Set;

/**
 * spring security自定义权限认证
 * 结合  @PreAuthorize(value="spring el表达式")
 * 代码参照 SecurityExpressionRoot。java
 */
@Component(value = "ss")
public class ShopSecurityExpressRoot {

    private String defaultRolePrefix = "ROLE_";

    /**
     * 代表菜单拥有所有权限
     */
    private String PERMIS_ALL="*:*:*";


    /**
     * 验证是否有某种角色
     * @param role
     * @return
     */
    public final boolean hasRole(String role) {
        return hasAnyRole(role);
    }

    /**
     * 验证是否有某些角色
     * @param roles
     * @return
     */
    public final boolean hasAnyRole(String... roles) {
        return hasAnyAuthorityName(this.defaultRolePrefix, roles);
    }

    /**
     * 验证是否有某个菜单权限(管理员和商家)
     * @param authority
     * @return
     */
    public final boolean hasAuthority(String authority) {
        return hasAnyAuthority(authority);
    }

    /**
     * 验证是否有某些菜单权限
     * @param authorities
     * @return
     */
    public final boolean hasAnyAuthority(String... authorities) {
        return hasAnyAuthorityName(null, authorities);
    }



    /**
     * 验证管理员和商家的权限
     * @param prefix
     * @param roles
     * @return
     */
    private boolean hasAnyAuthorityName(String prefix, String... roles) {
        Set<String> roleSet = getAuthoritySet();

        //如果角色或菜单中包含 *:*:*，说明你是超级管理员，不要再计算了
        if(roleSet.contains(PERMIS_ALL)){
            return true;
        }

        for (String role : roles) {
            String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
            if (roleSet.contains(defaultedRole)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 拼接前缀ROLE_
     * @param defaultRolePrefix
     * @param role
     * @return
     */
    private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
        if (role == null) {
            return role;
        }
        if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
            return role;
        }
        if (role.startsWith(defaultRolePrefix)) {
            return role;
        }
        return defaultRolePrefix + role;
    }

    /**
     * 得到当前登录用户所有的权限，获取 AdminLoginVO.getAuthorities() 把转换为Set<String>
     * @return
     */
    private Set<String> getAuthoritySet() {

        //通过当前线程，取得对象
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();

        Collection<? extends GrantedAuthority> userAuthorities = authentication.getAuthorities();

        Set<String> roles = AuthorityUtils.authorityListToSet(userAuthorities);

        return roles;
    }
}
